﻿#include "B7CutPanelMatcher.h"
#include <opencv2/highgui.hpp>
#include "qtOpenCV/plinesfit_opencv.h"
#include "qtOpenCV/convert.h"
#include <QString>
#include <QDir>
#include <QDebug>
#include <QApplication>
#include <QSettings>
#include "RecipeLoader.h"

//dir =
enum DIR {LEFT_TO_RIGHT = 0, RIGHT_TO_LEFT = 1, UP_TO_DOWN = 2, DOWN_TO_UP = 3};
const int BORDER = 10;

B7CutPanelMatcher::B7CutPanelMatcher()
{
}


bool B7CutPanelMatcher::panelDetect(QImage &image, QString leftid, QString rightid)
{
    cv::Mat matColorImage = QImage2cvMat(image);
    cv::Mat matGray;
    cv::cvtColor(matColorImage, matGray, cv::COLOR_BGR2GRAY);
    cv::Point pt;

    // big panel 模式 的 id 在 rightid 位置。这时我们需要把id 挪到 leftid 的位置。
    // 因为 rightid 对应 locator[1]， locator[1] 是空的。
    if(isOnePanelMode())
    {
        /// 说明是big panel 模式 或者 QPanel 模式
        leftid = rightid;
        rightid = QString();
    }

    m_panelCount = 0;
    m_hasLeftPanel = !(leftid.isEmpty() || leftid.isNull());
    m_hasRightPanel = !(rightid.isEmpty() || rightid.isNull());

    m_leftPanelLocateFailed = true;
    m_rightPanelLocateFailed = true;
    if(m_modelCount == 1)
    {
        if( m_hasLeftPanel ) //有 id 说明有 Panel。这时应该检测
        {
            int ret = locator[0].panelDetect(matGray);
            if(ret == 1)
            {
                m_leftPanelLocateFailed = false;
                m_panelCount ++;
            }
        }
        if( m_hasRightPanel )
        {
            int ret = locator[1].panelDetect(matGray);
            if(ret == 1)
            {
                m_rightPanelLocateFailed = false;
                m_panelCount ++;
            }
        }
    }
    else
    {
        double minDeviation = 10000;
        int index = -1;
        for(int i = 0 ;i < m_modelCount; i++)
        {
            locator[i].m_score = 0.0;
            int devi = locator[i].panelSizeDeviate(matGray);
            qDebug() << "i = " << i << ", dev = " << devi;
            if(devi < minDeviation)
            {
                minDeviation = devi;
                index = i;
            }
        }
        if(index != -1)
        {
            qDebug() << "index = " << index << ", minDeviation = " << minDeviation;
            int ret = locator[index].panelDetect(matGray);
            if(ret == 1)
            {
                m_leftPanelLocateFailed = false;
            }
        }

    }
    return true;
}

bool B7CutPanelMatcher::loadRecipe(QString recipeName)
{
    for(int i = 0; i < 8; i++)
    {
        locator[i].m_valid = false;
    }
    QString recipeFileName = m_recipePath + "/" + recipeName + ".ini";
    QDir dir(recipeFileName);
    if(!dir.exists(recipeFileName)) // 没有模板文件
    {
        qDebug() << "recipe file not exists";
        m_valid = false;
        return false;
    }
    QSettings settings( recipeFileName, QSettings::IniFormat );
    m_modelCount = settings.value("ModelCount", 1).toInt();
    qDebug() << "m_modelCount = " << m_modelCount;
    RecipeLoader loader;
    if(m_modelCount == 1)
    {
        loader.loadRecipe_Left(m_recipePath, recipeName, (locator[0]));
        loader.loadRecipe_Right(m_recipePath, recipeName, (locator[1]));
    }
    else
    {
        for(int i = 0; i < m_modelCount; i++)
        {
            QString recipeName_multi = QString("%1_%2").arg(recipeName).arg(i);
            loader.loadRecipe_Left(m_recipePath, recipeName_multi, (locator[i]));
        }
    }
    qDebug() << "loadRecipe is OK";
    m_recipeName = recipeName;
    return true;
}


void B7CutPanelMatcher::getData(double scale, double x[2], double y[2], double theta[2], double score[2], int &N)
{
    x[0] = x[1] = y[0] = y[1] = 0.0;
    theta[0] = theta[1] = 0.0;
    score[0] = score[1] = 0;
    if(m_modelCount == 1 && locator[1].m_valid)
    { // 这时不是 big panel 模式
        N = 2;
        if(m_hasRightPanel)
        {
            x[0] = locator[1].m_shift.x * scale / 1000.0;
            y[0] = locator[1].m_shift.y * scale / 1000.0;
            theta[0] = locator[1].m_rotateTheta;
            score[0] = locator[1].m_score;   
        }
        if(m_hasLeftPanel)
        {
            x[1] = locator[0].m_shift.x * scale / 1000.0;
            y[1] = locator[0].m_shift.y * scale / 1000.0;
            theta[1] = locator[0].m_rotateTheta;
            score[1] = locator[0].m_score;
        }
    }
    else if(m_modelCount == 1 && (locator[1].m_valid == false) )
    { //是 big panel 模式
        if(m_hasLeftPanel)
        {
            x[0] = locator[0].m_shift.x * scale / 1000.0;
            y[0] = locator[0].m_shift.y * scale / 1000.0;
            theta[0] = locator[0].m_rotateTheta;
            score[0] = locator[0].m_score;
        }
        N = 1;
    }
    else
    {
        N = 1;
        double maxScore = -1;
        int index = 0;
        for(int i = 0 ;i < m_modelCount; i++)
        {
            if(locator[i].m_score > maxScore)
            {
                maxScore = locator[i].m_score;
                index = i;
            }
        }
        x[0] = locator[index].m_shift.x * scale / 1000.0;
        y[0] = locator[index].m_shift.y * scale / 1000.0;
        theta[0] = locator[index].m_rotateTheta;
        score[0] = locator[index].m_score;
    }
}

bool B7CutPanelMatcher::isOnePanelMode()
{
    if(m_modelCount > 1) return true;
    if(locator[1].m_valid == false ) return true;
    return false;
}

QVector<QRect> B7CutPanelMatcher::panelRects()
{
    QVector<QRect> rects;
    for(int i = 0; i < 8; i ++ )
    {
        //qDebug() << "i = " << i << ", valid = " << locator[i].m_valid;
        if( locator[i].m_valid ) rects.push_back(locator[i].m_panelRect);
    }
    return rects;
}

QRect B7CutPanelMatcher::leftPanelRect()
{
    return locator[0].m_panelRect;
}

QRect B7CutPanelMatcher::rightPanelRect()
{
    return locator[1].m_panelRect;
}

QString B7CutPanelMatcher::recipeName()
{
    if(m_modelCount == 1) return m_recipeName;
    double maxScore = 0;
    int index;
    for(int i = 0 ;i < m_modelCount; i++)
    {
        if(locator[i].m_score > maxScore)
        {
            maxScore = locator[i].m_score;
            index = i;
        }
    }
    return locator[index].m_recipeName;
}



